using GMS.NET.Core.Entitys.System;
using GMS.NET.Dto.System.Menus.Enums;
using GMS.NET.Dto.System.Menus.Shared;
using Mapster;
using System.Text;

namespace GMS.NET.Application.Service.System.Menus
{
    [Authorize]
    [DynamicApiController]
    public class MenusService : DbManger, IMenusService
    {
        public async Task DelMenusTree([FromBody] List<Guid> Ids)
        {
            foreach (var Id in Ids)
            {
                var MenuItems = await MasterDb.Queryable<GMSNet_Resouce>()
                .OrderBy(x => x.Res_Sort, OrderByType.Asc)
                .ToTreeAsync(it => it.Children, it => it.Res_ParentId, Id);

                var sonIds = GetMenustemIds(MenuItems);

                //删除所有子项
                await MasterDb.Deleteable<GMSNet_Resouce>()
                    .Where(x => sonIds.Contains(x.Id))
                    .ExecuteCommandAsync();
            }

            //删除当前项
            await MasterDb.Deleteable<GMSNet_Resouce>()
                .Where(x => Ids.Contains(x.Id))
                .ExecuteCommandAsync();
        }
        private List<Guid> GetMenustemIds(List<GMSNet_Resouce> treeNodes)
        {
            List<Guid> ids = new List<Guid>();

            if (treeNodes is not null)
                foreach (var node in treeNodes)
                {
                    ids.Add(node.Id);
                    ids.AddRange(GetMenustemIds(node.Children!));
                }
            return ids;
        }
        [HttpPost]
        public async Task<List<MenusTree>> GetMenusTree([FromBody] Guid ParentId)
        {
            var MenuList = await MasterDb.Queryable<GMSNet_Resouce>()
                .Where(x => x.Res_ParentId == ParentId)
                .Select<MenusTree>()
                .OrderBy(x => x.Res_Sort, OrderByType.Asc)
                .ToListAsync();
            return MenuList;
        }
        [HttpPost]
        public async Task<List<KeyValues>> GetParentList([FromBody] string Text)
        {
            var menuList = await MasterDb.Queryable<GMSNet_Resouce>()
                .Where(x => x.Res_Name!.Contains(Text))
                .Select(x => new KeyValues
                {
                    Key = x.Res_Name,
                    Value = x.Id
                })
                .ToListAsync();

            return menuList;
        }
        public async Task SaveMenusTree([FromBody] MenusTree menusTree)
        {
            //Mapster自动映射
            var PramMenus = menusTree.Adapt<GMSNet_Resouce>();
            if (PramMenus.Id != Guid.Empty)
            {
                var OrgMenus = await MasterDb.Queryable<GMSNet_Resouce>().InSingleAsync(PramMenus.Id);
                var UpdateMenus = menusTree.Adapt<GMSNet_Resouce>();
                UpdateMenus.Creationtime = OrgMenus.Creationtime;
                UpdateMenus.Creator = OrgMenus.Creator;
                await MasterDb.Updateable(UpdateMenus)
                    .CallEntityMethod(it => it.SetUpdateUser())
                    .ExecuteCommandAsync();
            }
            else
            {
                if (menusTree.IsOpenCodeCreate)
                {
                    var basePath = App.HostEnvironment.ContentRootPath.Split(new string[] { "src" }, StringSplitOptions.None)[0] + "src\\GMS.NET.Application\\Service\\";
                    //生成类
                    if (menusTree.Res_Type == Res_Type.sysmenu)
                    {
                        if (!string.IsNullOrWhiteSpace(menusTree.Res_CodeName)
                            && !string.IsNullOrWhiteSpace(menusTree.Res_CsFileCatalog))
                        {
                            var path1 = FileTool.ThisDirectoryCreateDirectory(basePath, menusTree.Res_CsFileCatalog);
                            var path2 = FileTool.ThisDirectoryCreateDirectory(path1, menusTree.Res_CodeName);
                            var IcsPath = Path.Combine(path2, $"I{menusTree.Res_CodeName}Service.cs");
                            var csPath = Path.Combine(path2, $"{menusTree.Res_CodeName}Service.cs");
                            StringBuilder Icssb = new StringBuilder();
                            Icssb.AppendLine($"namespace GMS.NET.Application.Service.{menusTree.Res_CsFileCatalog}.{menusTree.Res_CodeName}");
                            Icssb.AppendLine("{");
                            Icssb.AppendLine("\t/// <summary>");
                            Icssb.AppendLine($"\t/// {menusTree.Res_Name}");
                            Icssb.AppendLine("\t/// </summary>");
                            Icssb.AppendLine($"\tpublic interface I{menusTree.Res_CodeName}Service");
                            Icssb.AppendLine("\t{");
                            Icssb.AppendLine("\t}");
                            Icssb.AppendLine("}");
                            StringBuilder cssb = new StringBuilder();
                            cssb.AppendLine($"namespace GMS.NET.Application.Service.{menusTree.Res_CsFileCatalog}.{menusTree.Res_CodeName}");
                            cssb.AppendLine("{");
                            cssb.AppendLine("\t/// <summary>");
                            cssb.AppendLine($"\t/// {menusTree.Res_Name}");
                            cssb.AppendLine("\t/// </summary>");
                            cssb.AppendLine("\t[Authorize]");
                            cssb.AppendLine("\t[DynamicApiController]");
                            cssb.AppendLine($"\tpublic class {menusTree.Res_CodeName}Service :  DbManger, I{menusTree.Res_CodeName}Service");
                            cssb.AppendLine("\t{");
                            cssb.AppendLine("\t}");
                            cssb.AppendLine("}");
                            File.WriteAllText(IcsPath, Icssb.ToString());
                            File.WriteAllText(csPath, cssb.ToString());
                        }
                    }
                    //生成方法
                    if (menusTree.Res_Type == Res_Type.apiInterface)
                    {
                        PramMenus.Id = Guid.NewGuid();
                        if (!string.IsNullOrWhiteSpace(menusTree.Res_CodeName)
                            && !string.IsNullOrWhiteSpace(menusTree.Res_CsFileName))
                        {
                            basePath= Path.Combine(basePath, menusTree.Res_CsFileCatalog!);
                            basePath = Path.Combine(basePath, menusTree.Res_CsFileName!);
                            //接口
                            var IcsFile = Path.Combine(basePath, $"I{menusTree.Res_CsFileName}Service.cs");
                            string IcsContent = File.ReadAllText(IcsFile!);
                            StringBuilder Isb = new();
                            Isb.AppendLine($"/// <summary>");
                            Isb.AppendLine($"/// {menusTree.Res_Name}");
                            Isb.AppendLine($"/// </summary>");
                            Isb.AppendLine($"/// <returns></returns>");
                            Isb.AppendLine($"Task {menusTree.Res_CodeName}();");
                            IcsContent = ApiCodeTool.ModifyAndAddInterfaceMethod(IcsContent, Isb);
                            File.WriteAllText(IcsFile!, IcsContent);
                            //方法
                            var csFile = Path.Combine(basePath, $"{menusTree.Res_CsFileName}Service.cs");
                            string csContent = File.ReadAllText(csFile!);
                            StringBuilder Sb = new ();
                            Sb.AppendLine($"/// <summary>");
                            Sb.AppendLine($"/// {menusTree.Res_Name}");
                            Sb.AppendLine($"/// </summary>");
                            Sb.AppendLine($"/// <returns></returns>");
                            Sb.AppendLine($"[SecurityDefine(\"{PramMenus.Id.ToString()}\")]");
                            Sb.AppendLine($"public Task {menusTree.Res_CodeName}()=>Task.CompletedTask;");
                            csContent = ApiCodeTool.ModifyAndAddInterfaceMethod(csContent, Sb);
                            File.WriteAllText(csFile!, csContent);
                        }
                    }
                }

                //插入调用赋值方法
                await MasterDb.Insertable(PramMenus)
                    .CallEntityMethod(it => it.SetAddUser())
                    .ExecuteCommandAsync();
            }
        }
        public async Task MenusTreeStatus(int status, Guid Id)
        {
            //子项递归列表
            var MenusTreeSon = await MasterDb.Queryable<GMSNet_Resouce>()
                  .OrderBy(x => x.Res_Sort, OrderByType.Asc)
                  .ToTreeAsync(it => it.Children, it => it.Res_ParentId, Id);

            if (MenusTreeSon.Count > 0)
            {
                //子项Id集合
                var sonIds = GetMenustemIds(MenusTreeSon);

                //修改当前项的子项
                await MasterDb.Updateable<GMSNet_Resouce>()
                    .SetColumns(x => x.Res_Disabled == status)
                    .Where(x => sonIds.Contains(x.Id))
                    .ExecuteCommandAsync();
            }

            //修改当前项
            await MasterDb.Updateable<GMSNet_Resouce>()
                .SetColumns(x => x.Res_Disabled == status)
                .Where(x => x.Id == Id)
                .ExecuteCommandAsync();
        }
        [HttpPost]
        public async Task<CodeCSInfo> GetCodeInfo(Guid Id)
        {
            var result= await MasterDb.Queryable<GMSNet_Resouce>()
                .Where(x => x.Id == Id)
                .Select(x => new CodeCSInfo{Res_CsFileName=x.Res_CodeName },true)
                .FirstAsync();
            return result;
        }
    }
}